# -*- coding: utf-8 -*-
"""
Module Description: 拦截器链

L1: 解析http请求为Request对象
L2: Request合法性校验,是否失效,白名单校验等
L3: 根据actionid,进行业务调用

L?: 日志处理
L?: 异常统一处理

暂不支持每个请求都可以自定义拦截器链,因此将拦截器链作为类变量

- 拦截器被用于处理前置逻辑;
- 在设计上pre和post是分隔开的,pre执行但post不一定会执行,取决于pre的返回值;
- post的后置逻辑目前看来没什么作用,后期需要优化.

Date: 2018/3/7
Author:Bai Jin Ping
"""
# from pyshare.framework.firefly_dc.global_errcode import GlobalErrCode
# from pyshare.framework.firefly_dc.globalobject import GlobalObject
#
# from pyshare.framework.interceptor.implement import request_format_interceptor
# from pyshare.framework.interceptor.implement import action_switch_interceptor
# from pyshare.framework.interceptor.implement import context_verify_interceptor
# from pyshare.framework.interceptor.implement import sender_interceptor
from framework.firefly_dc.global_errcode import GlobalErrCode
from framework.interceptor.implement import action_switch_interceptor, context_verify_interceptor


class InterceptorChain(object):
    """
    拦截器链, 用于装配拦截器.使用不纯的责任链模式实现
    """
    # 拦截器集合
    interceptors = []

    def __init__(self):
        # 当前执行到的拦截器位置
        self.idx = 0

    @classmethod
    def add_interceptor(cls, interceptor):
        """新增拦截器"""
        cls.interceptors.append(interceptor)
        return cls

    def apply_pre_process(self, request, response):
        """
        触发前置逻辑
        :param request:
        :param response:
        :return: bool
        """
        result = True
        for idx, interceptor in enumerate(self.interceptors):
            if not interceptor.pre_process(request=request, response=response):
                result = False
                break
            self.idx = idx

        # 拦截器的pre_process必须要设置非SUCCESS的响应状态
        if not result:
            assert response.stat != GlobalErrCode.SUCCESS

        return result

    def apply_post_process(self, request, response):
        """
        触发后置逻辑
        :param request:
        :param response:
        """
        if not self.interceptors:
            return
        for idx in range(self.idx, 0, -1):
            interceptor = self.interceptors[idx]
            interceptor.post_process(request=request, response=response)


def build_interceptor_chain():
    """装配拦截器链"""
    assert len(InterceptorChain.interceptors) == 0

    # 1.请求校验拦截器
    # InterceptorChain.add_interceptor(request_format_interceptor.RequestFormatInterceptor)
    # 2.调用者校验拦截器
    # InterceptorChain.add_interceptor(sender_interceptor.SenderInterceptor)

    # 3.上下文校验拦截器
    # if GlobalObject.is_cross_server():
    #     InterceptorChain.add_interceptor(context_verify_interceptor.CrossContextVerifyInterceptor)
    # else:
    InterceptorChain.add_interceptor(context_verify_interceptor.ContextVerifyInterceptor)
    #
    # 4.接口开关控制拦截器
    InterceptorChain.add_interceptor(action_switch_interceptor.ActionSwitchInterceptor)
